import { NextFunction, Request, Response } from "express";
import { UserService, PostService, CommentService } from "../services";
import { CommentSchema } from "../schemas";
import { paginate } from "../utils";
import { Like } from "typeorm";
import { RoleUser } from "../entities/user";

export class CommentController {
  public static async create(
    req: Request<unknown, unknown, CommentSchema>,
    res: Response,
    next: NextFunction,
  ) {
    try {
      const user = await UserService.findById(res.locals.user.id);
      const post = await PostService.findById(req.body.postId);
      if (!user || !post) {
        return res.status(400).json({
          status: "fail",
          message: "Invalid parameters",
        });
      }
      const comment = await CommentService.create({ ...req.body, user, post });
      res.status(201).json(comment);
    } catch (err) {
      next(err);
    }
  }

  public static async findOne(req: Request, res: Response, next: NextFunction) {
    try {
      const comment = await CommentService.findById(req.params.id);
      if (!comment) {
        return res.status(404).json({
          status: "fail",
          message: "Comment not found",
        });
      }
      res.json(comment);
    } catch (err) {
      next(err);
    }
  }

  public static async findMany(
    req: Request,
    res: Response,
    next: NextFunction,
  ) {
    try {
      const comments = await CommentService.find({
        ...paginate(req),
        where: { content: Like(`%${req.query.q || ""}%`) },
      });
      res.json({
        data: comments[0],
        total: comments[1],
      });
    } catch (err) {
      next(err);
    }
  }

  public static async update(req: Request, res: Response, next: NextFunction) {
    try {
      const comment = await CommentService.findById(req.params.id);
      if (!comment) {
        return res.status(404).json({
          status: "fail",
          message: "Post not found",
        });
      }
      if (
        res.locals.user.id !== comment.user.id &&
        res.locals.user.role !== RoleUser.ADMIN
      ) {
        return res.status(403).json({
          status: "fail",
          message: "Not allowed",
        });
      }
      await CommentService.update(comment.id, req.body);
      res.sendStatus(200);
    } catch (err) {
      next(err);
    }
  }

  public static async remove(req: Request, res: Response, next: NextFunction) {
    try {
      const comment = await CommentService.findById(req.params.id);
      if (!comment) {
        return res.status(404).json({
          status: "fail",
          message: "Post not found",
        });
      }
      if (
        res.locals.user.id !== comment.user.id &&
        res.locals.user.role !== RoleUser.ADMIN
      ) {
        return res.status(403).json({
          status: "fail",
          message: "Not allowed",
        });
      }
      await CommentService.remove(comment);
      res.sendStatus(200);
    } catch (err) {
      next(err);
    }
  }
}
